/*
 *	Yalala
 *	
 *	Copyright © MediaMonks B.V.
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	1. Redistributions of source code must retain the above copyright
 *	   notice, this list of conditions and the following disclaimer.
 *	2. Redistributions in binary form must reproduce the above copyright
 *	   notice, this list of conditions and the following disclaimer in the
 *	   documentation and/or other materials provided with the distribution.
 *	3. All advertising materials mentioning features or use of this software
 *	   must display the following acknowledgement:
 *	   This product includes software developed by MediaMonks B.V.
 *	4. Neither the name of MediaMonks B.V. nor the
 *	   names of its contributors may be used to endorse or promote products
 *	   derived from this software without specific prior written permission.
 *	
 *	THIS SOFTWARE IS PROVIDED BY MEDIAMONKS B.V. ''AS IS'' AND ANY
 *	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL MEDIAMONKS B.V. BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *	
 */

package com.mediamonks.yalala.ui 
{
	import temple.codecomponents.form.components.CodeAutoCompleteInputField;
	import temple.codecomponents.form.components.CodeCheckBox;
	import temple.codecomponents.label.CodeLabel;
	import temple.ui.form.Form;
	import temple.ui.form.FormEvent;
	import temple.ui.form.components.AutoCompleteInputField;
	import temple.ui.form.components.MultiElementComponent;
	import temple.ui.form.services.ObjectFormService;
	import temple.ui.tooltip.ToolTip;
	import temple.utils.TimeOut;
	import temple.utils.keys.KeyCode;

	import com.mediamonks.yalala.data.filters.StringFilter;
	import com.mediamonks.yalala.data.vo.SettingsData;
	import com.mediamonks.yalala.data.vo.StringFilterData;

	import flash.events.KeyboardEvent;
	import flash.utils.Dictionary;

	/**
	 * @author Thijs Broerse
	 */
	public class Header extends MultiElementComponent 
	{
		private static const _INPUT_WIDTH:Number = 100;
		private static const _CHECKBOX_WIDTH:Number = 70;
		private static const _LEFT_OFFSET:Number = 60;
		
		private var _timeOut:TimeOut;
		private var _settings:SettingsData;
		
		// Used to store a refference to the filter preset based on the field
		private var _fieldFilterPresetLookup:Dictionary;

		public function Header(settings:SettingsData, messageFilter:StringFilter, senderFilter:StringFilter, idFilter:StringFilter, stackFilter:StringFilter)
		{
			this._settings = settings;
			
			this._fieldFilterPresetLookup = new Dictionary();
			
			var filterLabel:CodeLabel = new CodeLabel("Filters:");
			this.addChild(filterLabel);
			filterLabel.x = 10;
			filterLabel.y = 3;
			
			this.addFilter(messageFilter, _LEFT_OFFSET, "message filter", "Filter messages on text.");
			this.addFilter(senderFilter, _LEFT_OFFSET + (_INPUT_WIDTH + _CHECKBOX_WIDTH), "sender filter", "Filter messages on sender.");
			this.addFilter(idFilter, _LEFT_OFFSET + (_INPUT_WIDTH + _CHECKBOX_WIDTH) * 2, "id filter", "Filer messages on sender id.");
			this.addFilter(stackFilter, _LEFT_OFFSET + (_INPUT_WIDTH + _CHECKBOX_WIDTH) * 3, "stack filter", "Filter messages on stack trace.");
		}

		private function addFilter(filter:StringFilter, x:Number, hintText:String, tooltipText:String):void 
		{
			var form:Form = new Form(new ObjectFormService(filter.data));
			form.addEventListener(FormEvent.SUBMIT_SUCCESS, this.handleFormEvent);
			form.tabFocusManager.loop = false;
			this.addElement(form.tabFocusManager);
			
			var field:CodeAutoCompleteInputField = new CodeAutoCompleteInputField(_INPUT_WIDTH);
			field.inSearch = true;
			field.caseSensitive = false;
			this.addChild(field);
			field.x = x;
			field.y = 2;
			field.hintText = hintText;
			field.submitOnChange = true;
			field.addEventListener(KeyboardEvent.KEY_DOWN, this.handleInputFieldKeyDown);
			form.addElement(field, StringFilterData.TEXT);
			
			field.addItems(this._settings.getFilterPreset(filter.field));
			this._fieldFilterPresetLookup[field] = filter.field;
			
			var checkBox:CodeCheckBox = new CodeCheckBox("RegExp", true);
			this.addChild(checkBox);
			checkBox.x = x + _INPUT_WIDTH + 4;
			checkBox.y = 3;
			checkBox.submitOnChange = true;
			form.addElement(checkBox, StringFilterData.IS_REGEXP);
			
			ToolTip.add(field, tooltipText + " \nPress 'Enter' to add your query to the pulldown. \nPress 'Delete' when selecting the item to delete from pulldown.");
			ToolTip.add(checkBox, "select checkbox to use Regular Expressions in the search box");
		}

		private function handleFormEvent(event:FormEvent):void 
		{
			switch (event.type)
			{
				case FormEvent.SUBMIT_SUCCESS:
					if (this._timeOut) this._timeOut.destruct();
					this._timeOut = new TimeOut(this.dispatchEvent, 1000, [new UIEvent(UIEvent.UPDATE)]);
					break;
			}
		}
		
		private function handleInputFieldKeyDown(event:KeyboardEvent):void 
		{
			var input:AutoCompleteInputField;
			
			switch (event.keyCode)
			{
				case KeyCode.ENTER:
				{
					// add value to list
					input = AutoCompleteInputField(event.currentTarget);
					
					if (input.value)
					{
						// check if value is already in list
						var item:*;
						var leni:int = input.length;
						for (var i : int = 0; i < leni; i++)
						{
							item = input.getItemAt(i);
							if (item == input.value)
							{
								input.removeItem(item);
								break;
							}
						}
						input.addItem(input.value);
						
						this._settings.addFilterPreset(this._fieldFilterPresetLookup[input], input.value);
					}
					break;
				}
				case KeyCode.DELETE:
				{
					// remove value from list
					input = AutoCompleteInputField(event.currentTarget);
					
					if (input.list.focus && input.selectedItem)
					{
						input.removeItem(input.selectedItem);
						input.filterItems();
						this._settings.removeFilterPreset(this._fieldFilterPresetLookup[input], input.value);
					}
					break;
				}
			}
		}
	}
}
